package main

import (
	"fmt"
	"os"
	"strings"

	"gitee.com/fhe-search/nfhedecd/NFHE_Function"
	"gitee.com/fhe-search/nfhedecd/denseComputiing"
	"gitee.com/fhe-search/nfhedecd/deviceKey"
	"gitee.com/fhe-search/nfhedecd/deviceManage"
	"gitee.com/fhe-search/nfhedecd/interfaceAPI"
	"gitee.com/fhe-search/nfhedecd/sessionKey"
)

const KeyAbsPath = "/home/huangheng/workspace/fhe-search/fhe-search-cloud/huangheng20240529/"

func NFHEDECDExample() {
	// sm1字符串加密
	{
		User_Auth_Password1 := interfaceAPI.ExportUserAuthPWPrefix(1, KeyAbsPath)
		plainData1 := "你好，世界！"
		encDataStr1, _ := denseComputiing.PEncStr(plainData1, 1)
		// 字符串解密
		var plainDataValue1 string
		plainDataValue1, _ = denseComputiing.PDecStr(encDataStr1, 1, User_Auth_Password1)
		plainDataValue1 = strings.TrimRight(plainDataValue1, "\000") // 去除多余的字节
		fmt.Println(plainData1 == plainDataValue1)
		fmt.Println(plainData1)
		fmt.Println(plainDataValue1)
		fmt.Println(strings.Compare(plainDataValue1, plainData1))
	}

	// fhe加密解密示例
	{
		plain := uint(123)
		encData, _ := NFHE_Function.NFHE_ENC(plain)
		decData, _ := NFHE_Function.NFHE_DEC(encData)
		if decData != plain {
			fmt.Println("同态加解密错误？", plain)
		} else {
			fmt.Println("同态加解密正确！", plain)
		}
	}
	deviceManage.NFHE_DECD_CloseDevice()
}

func UseHardWare(isUse bool) {
	if !isUse {
		return
	}
	if _, err := os.Stat("/dev/decd1"); os.IsNotExist(err) {
		panic("decd driver not load")
	}
	deviceManage.NFHE_DECD_OpenDevice()
	NFHEDECDInit(KeyAbsPath)
}

func NFHEDECDInit(fileNamePrefix string) {
	var errMsg error
	PasswordGlobal := "1234567812345678"     // 初始化管理员口令
	PasswordGlobalLen := len(PasswordGlobal) // 口令长度

	// 0-1 设备恢复出厂状态
	errMsg = deviceManage.DECD_Restore_FactorySetting(PasswordGlobal, PasswordGlobalLen)
	if errMsg == nil {
		fmt.Println("0-1 提示: 设备恢复出厂状态成功！")
	} else {
		panic(errMsg)
	}
	// 0-2 初始化设备
	errMsg = deviceManage.DECD_Kmg_Init_Device(PasswordGlobal, PasswordGlobalLen)
	if errMsg == nil {
		fmt.Println("0-2 提示: 初始化设备成功！")
	} else {
		panic(errMsg)
	}
	// 1 恢复保护密钥
	{
		var ProKeyvalue []byte
		ProKeyvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./02_NFHE_DECD_ProKey.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		errMsg := deviceKey.NFHE_DECD_Prokey_Restore(PasswordGlobal, PasswordGlobalLen, ProKeyvalue)
		if errMsg == nil {
			//fmt.Println("1 恢复保护密钥成功！", strings.ToUpper(hex.EncodeToString(ProKeyvalue[0:116])))
			fmt.Println("1 恢复保护密钥成功！")
		} else {
			panic(errMsg)
		}
	}

	// 2 恢复用户密钥
	{
		var UserKeyvalue []byte
		UserKeyvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./03_NFHE_DECD_UserKey.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		errMsg := deviceKey.NFHE_DECD_UserKey_Restore(PasswordGlobal, PasswordGlobalLen, UserKeyvalue)
		if errMsg == nil {
			//fmt.Println("2 恢复用户密钥成功！", strings.ToUpper(hex.EncodeToString(UserKeyvalue[0:192])))
			fmt.Println("2 恢复用户密钥成功！")
		} else {
			panic(errMsg)
		}
	}

	// 3 恢复密钥加密密钥
	{
		var KEKvalue []byte
		KEKvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./04_NFHE_DECD_KEK.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		errMsg := deviceKey.NFHE_DECD_KEK_Restore(PasswordGlobal, PasswordGlobalLen, KEKvalue)
		if errMsg == nil {
			//fmt.Println("3 恢复密钥加密密钥成功！", strings.ToUpper(hex.EncodeToString(KEKvalue[0:16])))
			fmt.Println("3 恢复密钥加密密钥成功！")
		} else {
			panic(errMsg)
		}
	}

	// 4 恢复同态公私钥对
	{
		//导入会话密钥
		var FHEPubKeyvalue []byte
		var FHEPriKeyvalue []byte
		FHEPubKeyvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./05_NFHE_DECD_FHEKey.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		FHEPriKeyvalue, errMsg = interfaceAPI.FileReadKeyByte(fileNamePrefix + "./06_NFHE_DECD_FHE_priKey.txt")
		if errMsg != nil {
			panic(errMsg)
		}
		errMsg = sessionKey.NFHE_DECD_Import_FHE_Key(1, FHEPubKeyvalue, FHEPriKeyvalue)
		if errMsg == nil {
			fmt.Println("4 恢复同态公钥成功！")
		} else {
			panic(errMsg)
		}
	}

	// 5 恢复SM1密钥
	{
		var i uint
		for i = 0; i < 64; i++ {
			s := fmt.Sprintf("%d", i)
			Ls_File_Name := "./SM1/07_NFHE_DECD_SM1_Key"
			Ls_File_Name += s
			Ls_File_Name = Ls_File_Name + ".txt"
			SM1Key_value, errMsg := interfaceAPI.FileReadKeyByte(fileNamePrefix + Ls_File_Name)
			if errMsg != nil {
				panic(errMsg)
			}
			errMsg = sessionKey.NFHE_DECD_Restore_SM1(i, SM1Key_value)
			if errMsg != nil {
				panic(errMsg)
			}
		}
		fmt.Println("5 恢复SM1密钥成功！")
	}

	// 6 恢复用户口令
	{
		var i uint
		for i = 0; i < 64; i++ {
			s := fmt.Sprintf("%d", i)
			Ls_File_Name := "./UAP/08_NFHE_DECD_Auth"
			Ls_File_Name += s
			Ls_File_Name = Ls_File_Name + ".txt"
			Auth_value, errMsg := interfaceAPI.FileReadKeyByte(fileNamePrefix + Ls_File_Name)
			//User_Auth_Password[i] = strings.ToUpper(hex.EncodeToString(Auth_value)[0:16])
			if errMsg != nil {
				panic(errMsg)
			}
			errMsg = sessionKey.NFHE_DECD_Restore_Auth(i, Auth_value)
			if errMsg != nil {
				panic(errMsg)
			}
		}
		fmt.Println("6 恢复用户权限口令成功！")
	}
}
